/**
 *  Copyright (C) 2013  Piotr Szczepański
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package main;


import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Random;
import java.util.Set;

import edu.pw.elka.gtsna.community_detection.CommunityStructure;
import edu.pw.elka.gtsna.graph.UndirectedGraph;
import edu.pw.elka.gtsna.graph_algorithms.CheckConnectivity;
import edu.pw.elka.gtsna.graph_creator.GMLReader;
import edu.pw.elka.gtsna.graph_creator.TGFCommunityStructureReader;
import edu.pw.elka.gtsna.graph_creator.TGFReader;
import edu.pw.elka.gtsna.graph_evaluators.Coverage;
import edu.pw.elka.gtsna.graph_evaluators.Modularity;
import edu.pw.elka.gtsna.interaction_index.InteractionIndex;
import edu.pw.elka.gtsna.interaction_index.kStepsDegreeII;
import edu.pw.elka.gtsna.weka_interface.InteractionClusterer;
import edu.pw.elka.gtsna.weka_interface.NodeInstances;



/**
 * @author Piotr Lech Szczepa�ski
 * @author P.Szczepanski@ii.pw.edu.pl 
 *
 */


public class Main {

	static DecimalFormat sixDForm;
	static NumberFormat nf;
	static Random rand = new Random();
	
	static {
		nf = NumberFormat.getNumberInstance(Locale.US);
		nf.setGroupingUsed(false);
		sixDForm = (DecimalFormat)nf;
		sixDForm.applyPattern("0.000000");
	}
	
	/**
	 * @param args
	 * @throws Exception 
	 */
	
	public static void processDataset(int stepsNumber, String dataset,
			String linkage, String interactionIndexType) throws Exception {
		System.out.println("Processing dataset: " + dataset);
		System.out.println("Steps number: " + stepsNumber);
		System.out.println("InteractionIndexType: " + interactionIndexType);
		System.out.println("Linkage: " + linkage);
		UndirectedGraph graph;
		if (dataset.endsWith(".tgf")) {
			graph = new UndirectedGraph(new TGFReader(dataset));
		} else {
			graph = new UndirectedGraph(new GMLReader(dataset));
		}
			
		CheckConnectivity cc = new CheckConnectivity(graph);
		cc.check(graph.getAllNodes());
		System.out.println("IS CONNECTED: "+cc.isConencted());
		System.out.println("GRAPH: "+graph.getNumOfNodes()+" "+graph.getNumOfEdges());
		
		NodeInstances instances = new NodeInstances(graph);
		InteractionClusterer clusterer = new InteractionClusterer(linkage);
		long startTime = System.currentTimeMillis();
		boolean buildFinalClusterer = false;
		clusterer.buildBestClusterer(instances, stepsNumber, interactionIndexType, buildFinalClusterer);
		long elapsedMs = System.currentTimeMillis() - startTime; 
		//System.out.println(clusterer.getModularities());
		//System.out.println(clusterer.getCoverages());
		System.out.println("nClusters: " + clusterer.getNumClusters());
	    System.out.println("modularity: " + clusterer.getModularity());
	    System.out.println("coverage: " + clusterer.getCoverage());
	    System.out.println("elapsed time: " + elapsedMs + "ms");
		//clusterer.plot();
	}


	public static void main(String[] args) throws Exception {
		
		//CommunityStructure cs = new CommunityStructure(new TGFCommunityStructureReader("zacharyCS.in"));
		//CommunityStructure cs2 = new CommunityStructure(new TGFCommunityStructureReader("zacharyCS2.in"));
		
		//UndirectedGraph g = new UndirectedGraph(new TGFReader("zachary.in"));
		
		
		//Modularity mod = new Modularity(g,cs);
		//Modularity mod2 = new Modularity(g,cs2);
		//System.out.println("modularity: "+mod.evaluate()+" "+mod2.evaluate());
		
		
		//AverageShortestPathsEvaluator  AD = new AverageShortestPathsEvaluator(g);
		//AverageDistanceInCommunities ADC = new AverageDistanceInCommunities(g,cs);

		
		//double ratio = ADC.evaluate()/AD.evaluate();
		
		//System.out.println(g.getNumOfNodes()+" "+g.getNumOfEdges());
	//	System.out.println(ratio);
		
		//int stepsNumber = 2; // for kStepsDegreeII

		//Set<Integer> C1 = new LinkedHashSet<Integer>();
		//Set<Integer> C2 = new LinkedHashSet<Integer>();
		
		//InteractionIndex ii = new kStepsDegreeII(g, stepsNumber);
		//ii.preComputation();
//		C1.add(17);C2.add(27);
//		System.out.println(ii.interaction(C1, C2));
//		System.out.println("********");
		
		
		//print(ii.interaction(17, 27));
		//print(ii.interaction(1, 34));
		//print(ii.interaction(4, 34));
		//print(ii.interaction(1, 29));
		//print(ii.interaction(17, 30));
		
		if (args.length < 2) {
			System.out.println("usage: ./program <datasetPath> <steps> <KSTEPS|NAIVE> <COMPLETE|SET|...>");
			return;
		}
		
		String dataset = args[0];
		int stepsNumber = Integer.parseInt(args[1]);
		String interactionIndexType = args.length > 2 ? args[2] : "KSTEPS";
		String linkage = args.length > 3 ? args[3] : "COMPLETE";
		
		processDataset(stepsNumber, dataset, linkage, interactionIndexType);
		
		
		//MSGVMAlgorithm msfva = new MSGVMAlgorithm(g);

		
	//	System.out.println(msfva.detectCommunities());
		
//		Runtime.getRuntime().exec("Rscript fastGreedy.R"); 
		
//		int iterations=100;
//		int K=10;
//		
//		GreedyModularity ltmud=new GreedyModularity(g, iterations, K);
	}
	
	static void print(double d){
		System.out.println(sixDForm.format(d));
	}

	static void print(String d){
		System.out.println(sixDForm.format(d));
	}

}
